package com.leo.entity;

import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.dsl.components.ExpireCleanComponent;
import com.almasb.fxgl.entity.Entity;
import com.almasb.fxgl.entity.EntityFactory;
import com.almasb.fxgl.entity.SpawnData;
import com.almasb.fxgl.entity.Spawns;
import com.almasb.fxgl.entity.components.ViewComponent;
import com.almasb.fxgl.physics.BoundingShape;
import com.almasb.fxgl.texture.AnimatedTexture;
import com.almasb.fxgl.texture.AnimationChannel;
import com.almasb.fxgl.texture.Texture;
import javafx.scene.image.Image;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: wangss
 * @CreateTime: 2023-06-02  12:37
 * @Description: TODO
 */
public class ImageEntityFactory implements EntityFactory {
    /**
     * 水平翻转图片
     *
     * @param spawnData
     * @return
     */
    @Spawns("car")
    public Entity createCar(SpawnData spawnData) {
        Texture leftCar = FXGL.texture("蝴蝶.png");
        Texture rightCar = leftCar.copy();
        // 用于在 JavaFX 应用程序中将节点水平翻转。它通过将节点沿 X 轴缩放 -1 的因子来实现翻转。这将使节点沿 X 轴翻转，并将其镜像显示
        rightCar.setScaleX(-1);
        // 移动
        rightCar.setTranslateX(leftCar.getWidth());
        return FXGL.entityBuilder(spawnData)
                .view(leftCar)
                .view(rightCar)
                .bbox(BoundingShape.box(leftCar.getWidth() * 2, leftCar.getHeight() * 2))
                .build();
    }

    /**
     * 序列帧图片操作
     *
     * @param spawnData
     * @return
     */
    @Spawns("boom")
    public Entity createBoom(SpawnData spawnData) {
        AnimationChannel an = new AnimationChannel(FXGL.image("explode_level_2.png", 450 * 2, 50 * 2), Duration.seconds(1), 9);
        AnimatedTexture at = new AnimatedTexture(an);
//        at.loop();
        at.play();
        return FXGL.entityBuilder(spawnData)
                .view(at)
                .with(new ExpireCleanComponent(Duration.seconds(1)))
                .build();
    }

    /**
     * 豌豆射手
     *
     * @param spawnData
     * @return
     */
    @Spawns("shooter")
    public Entity createShooter(SpawnData spawnData) {
        List<Image> imageList = new ArrayList<>();
        for (int i = 0; i <= 12; i++) {
            imageList.add(FXGL.image(String.format("豌豆射手/%d.png", i)));
        }
        AnimationChannel animationChannel = new AnimationChannel(imageList, Duration.seconds(1));
        AnimatedTexture at = new AnimatedTexture(animationChannel);
        at.loop();
        return FXGL.entityBuilder(spawnData)
                .view(at)
                .build();
    }

    @Spawns("miku")
    public Entity createMiku(SpawnData spawnData) {
        AnimationChannel ac = new AnimationChannel(FXGL.image("行走图/行走图.png"), 4, 40, 54, Duration.seconds(0.6), 0, 3);
        AnimatedTexture at = new AnimatedTexture(ac);
        at.loop();
        return FXGL.entityBuilder(spawnData)
                .view(at)
                .build();
    }

    @Spawns("run")
    public Entity createRun(SpawnData spawnData) {
        AnimationChannel ac = new AnimationChannel(FXGL.image("行走图/行走图2.png"), 8, 1024 / 8, 1024 / 8, Duration.seconds(1), 0, 7);
        AnimatedTexture at = new AnimatedTexture(ac);
        at.loop();
        return FXGL.entityBuilder(spawnData)
                .view(at)
                .build();
    }

    @Spawns("tank")
    public Entity createTank(SpawnData spawnData) {
        Texture texture = FXGL.texture("tank/tank.png");
        // 随机生成颜色
        Texture brighter = texture.multiplyColor(FXGLMath.randomColor()).brighter();
        Entity tank = FXGL.entityBuilder(spawnData)
                .view(brighter)
                .build();

        ViewComponent viewComponent = tank.getViewComponent();
        viewComponent.addOnClickHandler(mouseEvent -> {
            Texture node = (Texture) viewComponent.getChildren().get(0);
            node.dispose();
            viewComponent.clearChildren();
            viewComponent.addChild(FXGL.texture("tank/tank.png").multiplyColor(FXGLMath.randomColor()));
        });

        return tank;
    }
}
